package edu.tfh.s2.ehkbot.steuerung;

import java.io.Serializable;

import edu.tfh.s2.ehkbot.daten.Protokoll;

/**
 * Position speichert die Koordinaten des Raumes ab.
 * 
 * @author zehn
 * @version 1.0
 */
public class Position implements Serializable, Cloneable {
	private static final long serialVersionUID = -1089163523234761699L;

	private int x;
	private int y;
	private int z;

	public Position() {
		this.x = 0;
		this.y = 0;
		this.z = 0;
	}

	public Position(int x, int y, int z) {
		this.x = x;
		this.y = y;
		this.z = z;
	}

	/**
	 * Liefert den Abstamd zwischen zwei Punkten.
	 * 
	 * @param rhs
	 *            Der andere Punkt.
	 * @return Der Abstand [mm].
	 */
	public long abstand(Position rhs) {
		return (long) Math.sqrt(Math.pow(this.getX() - rhs.getX(), 2) + Math.pow(this.getY() - rhs.getY(), 2));
	}

	/**
	 * Addiert auf die aktuelle Position die andere Position.
	 * 
	 * @param rhs
	 *            Die andere Position.
	 * @return Die neue Position.
	 */
	public Position add(Position rhs) {
		x += rhs.getX();
		y += rhs.getY();
		z += rhs.getZ();
		return this;
	}

	/**
	 * @see java.lang.Object#clone()
	 */
	@Override
	public Object clone() {
		Position pos = null;
		try {
			pos = (Position) super.clone();
		} catch (CloneNotSupportedException e) {
			Protokoll.getInstanc().exception(e);
		}
		return pos;
	}

	/**
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!(obj instanceof Position))
			return false;

		Position rhs = (Position) obj;
		return this.getX() == rhs.getX() && this.getY() == rhs.getY() && this.getZ() == rhs.getZ();
	}

	/**
	 * Liefert die Koordinaten als 3 Elemente Vektor.
	 * 
	 * @return 3 Elemente Vektor.
	 */
	public int[] getKoordinate() {
		return new int[] { x, y, z };
	}

	/**
	 * Liefert die X Komponente.
	 * 
	 * @return Die X Komponente.
	 */
	public int getX() {
		return x;
	}

	/**
	 * Liefert die Y Komponente.
	 * 
	 * @return Die Y Komponente.
	 */
	public int getY() {
		return y;
	}

	/**
	 * Liefert die Z Komponente.
	 * 
	 * @return Die Z Komponente.
	 */
	public int getZ() {
		return z;
	}

	/**
	 * Gibt die richtung zurück die von zwei Punkten gebildet wird.
	 * 
	 * @param rhs
	 *            Die andere Position.
	 * @return Die Richtung.
	 */
	public Richtung richtung(Position rhs) {
		/*
		 * koordinaten in der map oben links ist (0|0) unten rechts ist (a|b) wobei a > 0 und b > 0 das ist
		 * das übliche koordinaten system bei Bildern/Karten
		 */
		double winkel = Math.atan2(this.getY() - rhs.getY(), rhs.getX() - this.getX());
		if (winkel < 0)
			return new Richtung(Math.PI + Math.PI + winkel);
		else
			return new Richtung(winkel);
	}

	/**
	 * Setzt die X Koordinate.
	 * 
	 * @param x
	 *            Die zu setzende Koordinate.
	 */
	public void setX(int x) {
		this.x = x;
	}

	/**
	 * Setzt die Y Koordinate.
	 * 
	 * @param y
	 *            Die zu setzende Koordinate.
	 */
	public void setY(int y) {
		this.y = y;
	}

	/**
	 * Setzt die Z Koordinate.
	 * 
	 * @param z
	 *            Die zu setzende Koordinate.
	 */
	public void setZ(int z) {
		this.z = z;
	}

	/**
	 * Wandelt die Position in einen String um.
	 * 
	 * @return Die Präsentation als String.
	 */
	public String toString() {
		return "(" + x + "/" + y + "/" + z + ")";
	}
}